home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Environments / Small Eiffel 0.4.8 / lib_show / pyramid.e < prev    next >
Text File  |  1997-04-13  |  5KB  |  224 lines

  1. -- Part of SmallEiffel -- Read DISCLAIMER file -- Copyright (C) 
  2. -- Dominique COLNET and Suzanne COLLIN -- colnet@loria.fr
  3. --
  4. class PYRAMID 
  5. --
  6. -- Solving the problem of the Pyramid for small pyramid only.
  7. --
  8. --| This program uses the back-tracking method.
  9. --| Its goal is to try to fill a pyramid by making a substraction  
  10. --| between two succesive columns and to take its absolute value.  
  11. --| The result is put on the next line.   
  12. --| Example :
  13. --|  6 14 15 3 13
  14. --|   8 1 12 10
  15. --|    7 11 2
  16. --|     4  9
  17. --|       5 
  18. --
  19. -- See also pyramid2, which run faster than this first solution.
  20.    
  21. inherit ANY redefine print_on end;
  22.    
  23. creation
  24.    make
  25.  
  26. feature {ANY}
  27.    
  28.    size : INTEGER;
  29.    
  30.    make is
  31.       do
  32.      std_output.put_string("Want to compute a small pyramid ?%N%
  33.                 %Enter a small number (> 1) : ");
  34.      std_input.read_integer;
  35.      size := std_input.last_integer;
  36.      if size <= 1 then
  37.         std_output.put_string("You feel sick ?%N");
  38.      elseif size > biggest_one then
  39.         std_output.put_string("Value too big for this method.%N");
  40.      else
  41.         !!elem.make(1,max);
  42.         if fill_up(1) then
  43.            std_output.put_string("Full pyramid :%N");
  44.            print_on(std_output);
  45.         else
  46.            std_output.put_string("Unable to fill_up such one.%N");
  47.         end;
  48.      end;
  49.       end; -- make
  50.    
  51.    max : INTEGER is
  52.       do
  53.          Result := (size * (size + 1)) // 2;
  54.       end; -- max
  55.    
  56.    print_on(file: STD_FILE_WRITE) is
  57.       local
  58.      lig,col,nb : INTEGER;
  59.       do
  60.      from  
  61.         lig := 1;
  62.         col := 1;
  63.         nb := 0;
  64.      until
  65.         nb = max
  66.      loop
  67.         if col = 1 then
  68.            file.put_new_line;
  69.         end;
  70.         file.put_integer(elem.item(indice(lig,col)));
  71.         file.put_string(" ");
  72.         if col = size - lig + 1 then
  73.            col := 1 ;
  74.            lig := lig + 1 ;
  75.         else
  76.            col := col + 1;
  77.             end;
  78.         nb := nb + 1;
  79.      end;
  80.      file.put_new_line;
  81.       end; -- print_on
  82.    
  83.    belongs_to(nb : INTEGER): BOOLEAN is
  84.       require
  85.      nb_trop_petit: nb >= 1;
  86.      nb_trop_grand: nb <= max;
  87.       local
  88.      i : INTEGER;
  89.      trouve : BOOLEAN;
  90.       do
  91.      from  
  92.         i := 1;
  93.         trouve := false;
  94.      until
  95.         ((i > max) or trouve)
  96.      loop
  97.         trouve := (nb = elem.item(i));  
  98.         i := i + 1;
  99.      end;
  100.      Result := trouve;
  101.       end; -- belongs_to
  102.    
  103.    propagate (col, val_column_1: INTEGER): BOOLEAN is
  104.       require
  105.      val_column_1 >= 1;
  106.      val_column_1 <= max;
  107.      col >= 1;
  108.      col <= size;
  109.       local
  110.      stop : BOOLEAN;
  111.      lig : INTEGER;
  112.      val : INTEGER;
  113.       do
  114.          if belongs_to(val_column_1) then
  115.             Result := false ;
  116.          else
  117.             from  
  118.                elem.put(val_column_1,indice(1,col));
  119.                lig := 1;
  120.                val := val_column_1;
  121.                stop := false;
  122.                Result := true;
  123.             until
  124.                stop
  125.             loop
  126.                lig := lig + 1;
  127.                if lig > col then
  128.                   stop := true;
  129.                else
  130.                   val := val - elem.item(indice(lig-1,col-lig+1));
  131.                   if val < 0 then -- valeur absolue !
  132.                      val := - val ;
  133.                   end;
  134.                   if belongs_to(val) then
  135.                      clear_column(col);
  136.                      stop := true;
  137.                      Result := false;
  138.                   else
  139.                      elem.put(val,indice(lig,col-lig+1));
  140.                   end;
  141.                end;
  142.             end;
  143.          end;
  144.       end; -- propagate
  145.    
  146.    fill_up (col : INTEGER) : BOOLEAN is
  147.       require
  148.          col >= 1;
  149.       local
  150.          stop : BOOLEAN;
  151.          nb : INTEGER;
  152.       do
  153.          if col > size then
  154.             Result := true;
  155.          else
  156.             from  
  157.                stop := false;
  158.                nb := max;
  159.             until
  160.                stop
  161.             loop
  162.                if belongs_to(nb) then
  163.                   nb := nb - 1;
  164.                   stop := (nb = 0);
  165.            elseif propagate(col,nb) then          
  166.                   if  fill_up(col + 1) then            
  167.                      stop := true;
  168.                   else
  169.                      clear_column(col);
  170.                      nb := nb - 1;
  171.                      stop := (nb = 0);
  172.                   end;
  173.                else
  174.                   nb := nb - 1;
  175.                   stop := (nb = 0);
  176.                end;
  177.             end;
  178.             Result := (nb > 0);
  179.          end;
  180.       end; -- fill_up
  181.    
  182. feature {NONE}
  183.    
  184.    elem: ARRAY[INTEGER];
  185.    
  186.    case_vide : INTEGER is 0;
  187.    
  188.    biggest_one: INTEGER is 10;
  189.    
  190.    indice (lig,col : INTEGER): INTEGER is
  191.       require
  192.          lig_trop_petit: lig >= 1 ;
  193.          lig_trop_grand: lig <= size ;
  194.          col_trop_petit: col >= 1 ;
  195.          col_trop_grand: col <= size ;
  196.       local
  197.          l : INTEGER ;
  198.       do
  199.          l:= size - lig + 1;
  200.      Result := max - ((l * (l + 1)) // 2) + col;
  201.       ensure
  202.          Result >= 1 ;
  203.          Result <= max ;
  204.       end; -- indice
  205.    
  206.    clear_column (col : INTEGER) is
  207.       require
  208.          col >= 1;
  209.          col <= size;
  210.       local
  211.          lig : INTEGER;
  212.       do
  213.          from  
  214.             lig := 1;
  215.          until
  216.             lig > col
  217.          loop
  218.             elem.put(case_vide,indice(lig,col-lig+1));
  219.             lig := lig + 1;
  220.          end;
  221.       end; -- clear_column
  222.  
  223. end -- class PYRAMID
  224.